/*---------------------- modbus_tcp_ll.c ----------------------*/
#include "modbus_tcp_ll.h"

// ??????

extern uint16_t modbue_SlaveAddr;
extern uint16_t rtu_buff[1090];
extern uint8_t ModebusRxBuff[128];
//uint8_t ModebusRxBuff[MB_TCP_RX_BUF_SIZE];
extern uint8_t rx_usart1_cnt;
//volatile uint16_t rx_usart1_cnt = 0;




// ??????Modbus TCP??
void MB_TCP_Process(void) {
    // ??????(MBAP?+???)
    if(rx_usart1_cnt < 8) {
        rx_usart1_cnt = 0;
			  LL_USART_EnableIT_RXNE(USART1);
        return;
    }

    // ??MBAP?
    uint16_t trans_id = (ModebusRxBuff[0] << 8) | ModebusRxBuff[1];
    uint16_t proto_id = (ModebusRxBuff[2] << 8) | ModebusRxBuff[3];
    uint16_t length = (ModebusRxBuff[4] << 8) | ModebusRxBuff[5];
    uint8_t unit_id = ModebusRxBuff[6];
    uint8_t func_code = ModebusRxBuff[7];

    // ????
    if(proto_id != 0x0000 || unit_id != modbue_SlaveAddr) {
        rx_usart1_cnt = 0;
			  LL_USART_EnableIT_RXNE(USART1);
			  //LL_USART_TransmitData8(USART1, modbue_SlaveAddr);
        return;
    }

    uint8_t tx_buffer[MB_TCP_RX_BUF_SIZE];
    uint16_t tx_len = 0;
    uint8_t ex_code = 0;

    switch(func_code) {
        case 0x03: { // ??????
            if(rx_usart1_cnt != 12) {
                ex_code = 0x03; // ????
                break;
            }

            uint16_t start_addr = (ModebusRxBuff[8] << 8) | ModebusRxBuff[9];
            uint16_t reg_count = (ModebusRxBuff[10] << 8) | ModebusRxBuff[11];

            // ????
            if(start_addr + reg_count > MB_HOLDING_REG_NUM) {
                ex_code = 0x02; // ????
                break;
            }

            // ????
            tx_buffer[0] = trans_id >> 8;
            tx_buffer[1] = trans_id & 0xFF;
            tx_buffer[2] = 0x00; 
            tx_buffer[3] = 0x00;
            tx_buffer[4] = (3 + 2*reg_count) >> 8;
            tx_buffer[5] = (3 + 2*reg_count) & 0xFF;
            tx_buffer[6] = modbue_SlaveAddr;
            tx_buffer[7] = func_code;
            tx_buffer[8] = 2 * reg_count;

            for(int i=0; i<reg_count; i++) {
                tx_buffer[9 + 2*i] = rtu_buff[start_addr + i] >> 8;
                tx_buffer[10 + 2*i] = rtu_buff[start_addr + i] & 0xFF;
            }
            tx_len = 9 + 2*reg_count;
            break;
        }

        case 0x06: { // ??????
            if(rx_usart1_cnt != 12) {
                ex_code = 0x03;
                break;
            }

            uint16_t reg_addr = (ModebusRxBuff[8] << 8) | ModebusRxBuff[9];
            uint16_t reg_value = (ModebusRxBuff[10] << 8) | ModebusRxBuff[11];

            if(reg_addr >= MB_HOLDING_REG_NUM) {
                ex_code = 0x02;
                break;
            }

            rtu_buff[reg_addr] = reg_value;
            memcpy(tx_buffer, ModebusRxBuff, 12);
            tx_len = 12;
            break;
        }

        case 0x10: { // ??????
            if(rx_usart1_cnt < 13) {
                ex_code = 0x03;
                break;
            }

            uint16_t start_addr = (ModebusRxBuff[8] << 8) | ModebusRxBuff[9];
            uint16_t reg_count = (ModebusRxBuff[10] << 8) | ModebusRxBuff[11];
            uint8_t byte_count = ModebusRxBuff[12];
            uint16_t cc = (ModebusRxBuff[13] << 8) | ModebusRxBuff[14];
						uint16_t in = (ModebusRxBuff[15] << 8) | ModebusRxBuff[16];
						uint16_t va = (ModebusRxBuff[17] << 8) | ModebusRxBuff[18];
            if(start_addr + reg_count > MB_HOLDING_REG_NUM || 
               byte_count != 2*reg_count) {
                ex_code = 0x03;
                break;
            }
							if(start_addr < 0x800) {
            for(int i=0; i<reg_count; i++) {
                rtu_buff[start_addr + i] = 
                    (ModebusRxBuff[13 + 2*i] << 8) | ModebusRxBuff[14 + 2*i];
            }}else{
						if(cc ==0xaaaa)
							{
							v_k[(in-1)]=v_k[(in-1)]* (((float)va /100.00)/dc_v[(in-1)]);			
						//	v_k[1]=v_k[1]* (((float)RegBuff[3] /100.00)/dc_v[1]);					
						//	v_k[2]=v_k[2]* (((float)RegBuff[4] /100.00)/dc_v[2]);									
							writeFlashTest();	
							}
							
							if(cc ==0xbbbb)
							{
								if(dc_i[(in-1)] > 0){
						    i_k_a[(in-1)]=i_k_a[(in-1)]*(((float)va /100.00)/dc_i[(in-1)]);		
								}else{
								i_k_a[(in-1)]=0-(i_k_a[(in-1)]*(((float)va /100.00)/dc_i[(in-1)]));
								}
						  //  i_k_a[1]=i_k_a[1]*(((float)RegBuff[3] /100.00)/dc_i[1]);	
						  //  i_k_a[2]=i_k_a[2]*(((float)RegBuff[4] /100.00)/dc_i[2]);									
							writeFlashTest();	
							}
						
						
						}
							

            tx_buffer[0] = trans_id >> 8;
            tx_buffer[1] = trans_id & 0xFF;
            tx_buffer[2] = 0x00;
            tx_buffer[3] = 0x00;
            tx_buffer[4] = 0x00;
            tx_buffer[5] = 0x06;
            tx_buffer[6] = modbue_SlaveAddr;
            tx_buffer[7] = func_code;
            tx_buffer[8] = start_addr >> 8;
            tx_buffer[9] = start_addr & 0xFF;
            tx_buffer[10] = reg_count >> 8;
            tx_buffer[11] = reg_count & 0xFF;
            tx_len = 12;
            break;
        }

        default:
            ex_code = 0x01; // ?????
            break;
    }
    
    // ????
    if(ex_code != 0) {
        MB_SendException(func_code, ex_code);
    } else {
        for(int i=0; i<tx_len; i++) {
            while(!LL_USART_IsActiveFlag_TXE(USART1)) {}
            LL_USART_TransmitData8(USART1, tx_buffer[i]);
        }
    }

    rx_usart1_cnt = 0;
		LL_USART_EnableIT_RXNE(USART1);
}

// ??????
void MB_SendException(uint8_t func, uint8_t excode) {
    uint8_t tx_buf[9] = {
        ModebusRxBuff[0], ModebusRxBuff[1], // ??ID
        0x00, 0x00,                      // ??ID
        0x00, 0x03,                      // ??
        modbue_SlaveAddr,
        func | 0x80,                     // ????
        excode
    };

    for(int i=0; i<9; i++) {
        while(!LL_USART_IsActiveFlag_TXE(USART1)) {}
        LL_USART_TransmitData8(USART1, tx_buf[i]);
    }
}